﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using iNet.Media.Imaging.Exif;
using iNet.Media.Xmp;

namespace iNet.Media.Imaging
{
	/// <summary>
	/// TIFF 影像解碼工作。
	/// </summary>
	public class TiffImageDecodeTask : BasicImageDecodeTask
	{
		#region 建構子
		/// <summary>
		/// 初始化新的 TiffImageDecodeTask 執行個體。
		/// </summary>
		public TiffImageDecodeTask()
			: base(ImageFormats.Tiff)
		{ }
		/// <summary>
		/// 初始化新的 TiffImageDecodeTask 執行個體。
		/// </summary>
		/// <param name="source">影像儲存來源。</param>
		public TiffImageDecodeTask(MediaStorage source)
			: base(ImageFormats.Tiff, source, 0, 0)
		{ }
		#endregion
		#region DecodeMetadataOverride
		internal override IMetadata DecodeMetadataOverride(Stream stream, bool isReadOnly)
		{
			//建立集合
			List<ExifTag> exifTags = new List<ExifTag>();
			List<XmpProperty> xmpProperties = new List<XmpProperty>();

			//取得中繼資料
			TiffReader headerReader = new TiffReader(stream);
			while (headerReader.ReadNextTag())
			{
				//取得 EXIF Tag
				ExifTag tag = headerReader.Tag;

				//取得 XMP 中繼資料
				if (tag != null && tag.ID == 700 && tag.Ifd == Ifd.Ifd0 && tag.Type == ExifTagType.Byte)
				{
					using (MemoryStream mStream = new MemoryStream(tag.Data))
					{
						using (XmpPropertyEnumerator xmpEnumerator = new XmpPropertyEnumerator(mStream))
						{
							while (xmpEnumerator.MoveNext())
								xmpProperties.Add(xmpEnumerator.Current);
						}
					}
					continue;
				}

				//取得一般中繼資料
				exifTags.Add(tag);
			}

			//回傳
			return new TiffMetadata(exifTags, xmpProperties, isReadOnly);
		}
		#endregion
		#region DecodePixelSize
		internal override Size<int> DecodePixelSize(Stream stream)
		{
			TiffReader headerReader = new TiffReader(stream);
			int? width = null, height = null;
			while (headerReader.ReadNextTag())
			{
				if (headerReader.TagId == 256)
				{
					ExifTag tag = headerReader.Tag;
					if (tag != null)
					{
						switch (tag.Type)
						{
							case ExifTagType.UInt16:
								width = tag.BitConverter.ToUInt16(tag.Data);
								break;
							case ExifTagType.UInt32:
								width = (int)tag.BitConverter.ToUInt32(tag.Data);
								break;
							case ExifTagType.Int16:
								width = tag.BitConverter.ToInt16(tag.Data);
								break;
							case ExifTagType.Int32:
								width = tag.BitConverter.ToInt32(tag.Data);
								break;
							default:
								continue;
						}
						if (height != null)
							return new Size<int>(width.Value, height.Value);
					}
				}
				else if (headerReader.TagId == 257)
				{
					ExifTag tag = headerReader.Tag;
					if (tag != null)
					{
						switch (tag.Type)
						{
							case ExifTagType.UInt16:
								height = tag.BitConverter.ToUInt16(tag.Data);
								break;
							case ExifTagType.UInt32:
								height = (int)tag.BitConverter.ToUInt32(tag.Data);
								break;
							case ExifTagType.Int16:
								height = tag.BitConverter.ToInt16(tag.Data);
								break;
							case ExifTagType.Int32:
								height = tag.BitConverter.ToInt32(tag.Data);
								break;
							default:
								continue;
						}
						if (width != null)
							return new Size<int>(width.Value, height.Value);
					}
				}
			}
			throw new MediaDecodeFailedException(MediaDecodeFailedReason.InvalidFormat);
		}
		#endregion
	}
}
